// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

// ************************************************************************* //
//  File: avtIsosurfaceFilter.C
// ************************************************************************* //

#include <avtIsosurfaceFilter.h>

#include <ContourOpAttributes.h>

#include <avtContourFilter.h>


// ****************************************************************************
//  Method: avtIsosurfaceFilter constructor
//
//  Programmer: childs -- generated by xml2info
//  Creation:   Tue Apr 16 10:37:31 PDT 2002
//
// ****************************************************************************

avtIsosurfaceFilter::avtIsosurfaceFilter()
{
    cf = NULL;
}


// ****************************************************************************
//  Method: avtIsosurfaceFilter destructor
//
//  Programmer: childs -- generated by xml2info
//  Creation:   Tue Apr 16 10:37:31 PDT 2002
//
//  Modifications:
//
// ****************************************************************************

avtIsosurfaceFilter::~avtIsosurfaceFilter()
{
    if (cf != NULL)
    {
        delete cf;
        cf = NULL;
    }
}


// ****************************************************************************
//  Method:  avtIsosurfaceFilter::Create
//
//  Programmer: childs -- generated by xml2info
//  Creation:   Tue Apr 16 10:37:31 PDT 2002
//
// ****************************************************************************

avtFilter *
avtIsosurfaceFilter::Create()
{
    return new avtIsosurfaceFilter();
}


// ****************************************************************************
//  Method:      avtIsosurfaceFilter::SetAtts
//
//  Purpose:
//      Sets the state of the filter based on the attribute object.
//
//  Arguments:
//      a        The attributes to use.
//
//  Programmer: childs -- generated by xml2info
//  Creation:   Tue Apr 16 10:37:31 PDT 2002
//
//  Modifications:
//    Brad Whitlock, Wed Mar 19 14:14:53 PDT 2014
//    Add callback to the facade filter.
//
// ****************************************************************************

void
avtIsosurfaceFilter::SetAtts(const AttributeGroup *a)
{
    atts = *(const IsosurfaceAttributes*)a;

    //
    // Construct a new contour filter based on these attributes.
    //
    if (cf != NULL)
    {
        delete cf;
    }
    ContourOpAttributes coa;
    coa.SetContourNLevels(atts.GetContourNLevels());
    coa.SetContourValue(atts.GetContourValue());
    coa.SetContourPercent(atts.GetContourPercent());
    coa.SetContourMethod(ContourOpAttributes::ContourMethod(
        atts.GetContourMethod()));
    coa.SetMinFlag(atts.GetMinFlag());
    coa.SetMaxFlag(atts.GetMaxFlag());
    coa.SetMin(atts.GetMin());
    coa.SetMax(atts.GetMax());
    coa.SetScaling(ContourOpAttributes::ContourScaling(atts.GetScaling()));
    coa.SetVariable(atts.GetVariable());
    cf = new avtContourFilter(coa);
    cf->ShouldCreateLabels(false);
    cf->SetUpdateDataObjectInfoCallback(UpdateDataObjectInfoCB, (void*)this);
}


// ****************************************************************************
//  Method: avtIsosurfaceFilter::Equivalent
//
//  Purpose:
//      Returns true if creating a new avtIsosurfaceFilter with the given
//      parameters would result in an equivalent avtIsosurfaceFilter.
//
//  Programmer: childs -- generated by xml2info
//  Creation:   Tue Apr 16 10:37:31 PDT 2002
//
// ****************************************************************************

bool
avtIsosurfaceFilter::Equivalent(const AttributeGroup *a)
{
    return (atts == *(IsosurfaceAttributes*)a);
}

// ****************************************************************************
//  Method: avtIsosurfaceFilter::GetFacadedFilter
//
//  Purpose:
//      Gets the filter that the filter that we are a facade of.
//
//  Programmer: Hank Childs
//  Creation:   April 16, 2002
//
// ****************************************************************************

avtFilter *
avtIsosurfaceFilter::GetFacadedFilter(void)
{
    return cf;
}

// ****************************************************************************
//  Method: avtIsosurfaceFilter::GetFacadedFilter
//
//  Purpose:
//      Gets the filter that the filter that we are a facade of.
//
//  Programmer: Tom Fogal
//  Creation:   June 23, 2009
//
// ****************************************************************************

const avtFilter *
avtIsosurfaceFilter::GetFacadedFilter(void) const
{
    return cf;
}

// ****************************************************************************
// Method: avtIsosurfaceFilter::UpdateDataObjectInfoCB
//
// Purpose:
//   Update the data object information.
//
// Programmer: Brad Whitlock
// Creation:   Tue Mar 18 10:53:05 PDT 2014
//
// Modifications:
//    Brad Whitlock, Mon Apr  7 15:55:02 PDT 2014
//    Add filter metadata used in export.
//    Work partially supported by DOE Grant SC0007548.
//
// ****************************************************************************

void
avtIsosurfaceFilter::UpdateDataObjectInfoCB(avtDataObject_p &input,
    avtDataObject_p &output, void *This)
{
    avtDataAttributes &outAtts = output->GetInfo().GetAttributes();
    const IsosurfaceAttributes &iso = ((const avtIsosurfaceFilter *)This)->atts;

    char tmp[200];
    std::string params;
    if(iso.GetContourMethod() == IsosurfaceAttributes::Level)
    {
        snprintf(tmp, 200, "contourNLevels=%d", iso.GetContourNLevels());
        params = tmp;
    }
    else if(iso.GetContourMethod() == IsosurfaceAttributes::Value)
    {
        params = "contourValue=";
        for(size_t i = 0; i < iso.GetContourValue().size(); ++i)
        {
            snprintf(tmp, 200, "%lg", iso.GetContourValue()[i]);
            params += tmp;
            if(i < iso.GetContourValue().size()-1)
                params += ", ";
        }
    }
    else if(iso.GetContourMethod() == IsosurfaceAttributes::Percent)
    {
        params = "contourPercent=";
        for(size_t i = 0; i < iso.GetContourPercent().size(); ++i)
        {
            snprintf(tmp, 200, "%lg", iso.GetContourPercent()[i]);
            params += tmp;
            if(i < iso.GetContourValue().size()-1)
                params += ", ";
        }
    }
    outAtts.AddFilterMetaData("Isosurface", params);
}
